import type { UploadFile } from 'antd';

/**
 * 文件类型映射
 */
export const FILE_TYPES = {
	IMAGE: ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'],
	DOCUMENT: [
		'application/pdf',
		'application/msword',
		'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
		'application/vnd.ms-excel',
		'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
	],
	ARCHIVE: ['application/zip', 'application/x-rar-compressed', 'application/x-7z-compressed']
} as const;

/**
 * 常用文件类型组合
 */
export const COMMON_ACCEPTS = {
	// 证件类文件
	CERTIFICATE: [...FILE_TYPES.IMAGE, 'application/pdf'],
	// 办公文档
	OFFICE: [...FILE_TYPES.DOCUMENT],
	// 图片
	IMAGE_ONLY: FILE_TYPES.IMAGE,
	// 所有支持的类型
	ALL: [...FILE_TYPES.IMAGE, ...FILE_TYPES.DOCUMENT, ...FILE_TYPES.ARCHIVE]
} as const;

/**
 * 获取文件扩展名
 */
export const getFileExtension = (filename: string): string => {
	return filename.slice(((filename.lastIndexOf('.') - 1) >>> 0) + 2);
};

/**
 * 根据文件类型获取图标
 */
export const getFileIcon = (file: UploadFile): string => {
	const type = file.type || '';
	const extension = getFileExtension(file.name || '').toLowerCase();

	if (type.startsWith('image/')) {
		return '🖼️';
	}

	if (type === 'application/pdf' || extension === 'pdf') {
		return '📄';
	}

	if (type.includes('word') || ['doc', 'docx'].includes(extension)) {
		return '📝';
	}

	if (type.includes('excel') || ['xls', 'xlsx'].includes(extension)) {
		return '📊';
	}

	if (type.includes('powerpoint') || ['ppt', 'pptx'].includes(extension)) {
		return '📺';
	}

	if (type.includes('zip') || ['zip', 'rar', '7z'].includes(extension)) {
		return '🗜️';
	}

	return '📎';
};

/**
 * 格式化文件大小
 */
export const formatFileSize = (bytes: number): string => {
	if (bytes === 0) return '0 B';

	const k = 1024;
	const sizes = ['B', 'KB', 'MB', 'GB'];
	const i = Math.floor(Math.log(bytes) / Math.log(k));

	return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

/**
 * 验证文件类型
 */
export const validateFileType = (file: File, allowedTypes: string[]): boolean => {
	return allowedTypes.includes(file.type);
};

/**
 * 验证文件大小
 */
export const validateFileSize = (file: File, maxSizeMB: number): boolean => {
	const maxSizeBytes = maxSizeMB * 1024 * 1024;
	return file.size <= maxSizeBytes;
};

/**
 * 将文件转换为base64
 */
export const fileToBase64 = (file: File): Promise<string> => {
	return new Promise((resolve, reject) => {
		const reader = new FileReader();
		reader.readAsDataURL(file);
		reader.onload = () => resolve(reader.result as string);
		reader.onerror = error => reject(error);
	});
};

/**
 * 压缩图片
 */
export const compressImage = (
	file: File,
	maxWidth: number = 1920,
	maxHeight: number = 1080,
	quality: number = 0.8
): Promise<File> => {
	return new Promise((resolve, reject) => {
		const canvas = document.createElement('canvas');
		const ctx = canvas.getContext('2d');
		const img = new Image();

		img.onload = () => {
			// 计算压缩后的尺寸
			let { width, height } = img;

			if (width > maxWidth || height > maxHeight) {
				const ratio = Math.min(maxWidth / width, maxHeight / height);
				width *= ratio;
				height *= ratio;
			}

			canvas.width = width;
			canvas.height = height;

			// 绘制压缩后的图片
			ctx?.drawImage(img, 0, 0, width, height);

			canvas.toBlob(
				blob => {
					if (blob) {
						const compressedFile = new File([blob], file.name, {
							type: file.type,
							lastModified: Date.now()
						});
						resolve(compressedFile);
					} else {
						reject(new Error('图片压缩失败'));
					}
				},
				file.type,
				quality
			);
		};

		img.onerror = () => reject(new Error('图片加载失败'));
		img.src = URL.createObjectURL(file);
	});
};

/**
 * 提取上传成功的文件URL列表
 */
export const extractFileUrls = (fileList: UploadFile[]): string[] => {
	return fileList
		.filter(file => file.status === 'done' && file.response?.url)
		.map(file => file.response.url);
};

/**
 * 将URL转换为UploadFile格式
 */
export const urlsToUploadFiles = (urls: string[]): UploadFile[] => {
	return urls.map((url, index) => ({
		uid: `${index}`,
		name: url.split('/').pop() ?? `file-${index}`,
		status: 'done',
		url
	}));
};

/**
 * 自定义上传请求
 */
export const customRequest = async options => {
	const { file, onSuccess, onError, onProgress } = options;

	const formData = new FormData();
	formData.append('file', file);

	try {
		const xhr = new XMLHttpRequest();

		// 上传进度
		xhr.upload.addEventListener('progress', event => {
			if (event.lengthComputable) {
				const percent = Math.round((event.loaded / event.total) * 100);
				onProgress({ percent });
			}
		});

		// 上传完成
		xhr.addEventListener('load', () => {
			if (xhr.status === 200) {
				const response = JSON.parse(xhr.responseText);
				onSuccess(response);
			} else {
				onError(new Error('上传失败'));
			}
		});

		// 上传错误
		xhr.addEventListener('error', () => {
			onError(new Error('上传失败'));
		});

		xhr.open('POST', '/api/upload');
		xhr.send(formData);
	} catch (error) {
		onError(error);
	}
};

/**
 * 预设的上传配置
 */
export const UPLOAD_PRESETS = {
	// 证件上传
	CERTIFICATE: {
		acceptTypes: COMMON_ACCEPTS.CERTIFICATE,
		maxCount: 2,
		maxSize: 5,
		listType: 'picture-card' as const,
		placeholder: '支持JPG、PNG、PDF格式，最多2个文件，单个文件不超过5MB'
	},

	// 头像上传
	AVATAR: {
		acceptTypes: FILE_TYPES.IMAGE,
		maxCount: 1,
		maxSize: 2,
		listType: 'picture-circle' as const,
		placeholder: '支持JPG、PNG格式，文件大小不超过2MB'
	},

	// 文档上传
	DOCUMENT: {
		acceptTypes: COMMON_ACCEPTS.OFFICE,
		maxCount: 10,
		maxSize: 20,
		listType: 'text' as const,
		placeholder: '支持PDF、Word、Excel格式，最多10个文件'
	},

	// 图片相册
	GALLERY: {
		acceptTypes: FILE_TYPES.IMAGE,
		maxCount: 9,
		maxSize: 10,
		listType: 'picture-card' as const,
		placeholder: '支持JPG、PNG格式，最多9张图片'
	}
} as const;
